package br.com.ia.test;

import java.io.FileReader;
import java.io.StreamTokenizer;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Vector;

public class RuleBase {
	String fileName;
	WorkingMemory wm;
	Vector rules;

	StreamTokenizer st;
	FileReader f;

	RuleBase() {
		fileName = "C:/Users/Geissivan/Desktop/CarShop.data";
		wm = new WorkingMemory();
		wm.addAssertion("my-car is inexpensive");
		wm.addAssertion("my-car is a wagon");
		rules = new Vector();
		loadRules(fileName);
	}

	private String instantiate(String thePattern, Hashtable theBindings) {
		String result = new String();
		StringTokenizer st = new StringTokenizer(thePattern);
		for (int i = 0; i < st.countTokens();) {
			String tmp = st.nextToken();
			if (var(tmp)) {
				result = result + " " + (String) theBindings.get(tmp);
			} else {
				result = result + " " + tmp;
			}
		}
		return result.trim();

	}

	private boolean var(String str1) {
		return str1.startsWith("?");
	}

	private void loadRules(String theFileName) {
		String line;
		try {
			int token;
			f = new FileReader(theFileName);
			st = new StreamTokenizer(f);
			while ((token = st.nextToken()) != StreamTokenizer.TT_EOF) {
				switch (token) {
				case StreamTokenizer.TT_WORD:
					String name = null;
					Vector antecedents = null;
					String consequent = null;
					if ("rule".equals(st.sval)) {
						if (st.nextToken() == '"') {
							name = st.sval;
							st.nextToken();
							if ("if".equals(st.sval)) {
								antecedents = new Vector();
								st.nextToken();
								while (!"then".equals(st.sval)) {
									antecedents.addElement(st.sval);
									st.nextToken();
								}

								if ("then".equals(st.sval)) {
									st.nextToken();
									consequent = st.sval;
								}
							}
						}
					}
					rules.addElement(new Rule(name, antecedents, consequent));
					break;
				default:
					System.out.println(token);
					break;
				}
			}
		} catch (Exception e) {
			System.out.println(e);
		}
		for (int i = 0; i < rules.size(); i++) {
			System.out.println(((Rule) rules.elementAt(i)).toString());
		}
	}

	public void forwardChain() {
		boolean newAssertionCreated;
		// 
		do {
			newAssertionCreated = false;
			for (int i = 0; i < rules.size(); i++) {
				Rule aRule = (Rule) rules.elementAt(i);
				System.out.println("apply rule:" + aRule.getName());
				Vector antecedents = aRule.getAntecedents();
				String consequent = aRule.getConsequent();
				// Hashtable bindings = wm.matchingAssertions(antecedents);
				Vector bindings = null;
				if(antecedents != null){
					bindings = wm.matchingAssertions(antecedents);
				}
				if (bindings != null) {
					for (int j = 0; j < bindings.size(); j++) {
						String newAssertion = instantiate((String) consequent,
								(Hashtable) bindings.elementAt(j));
						if (!wm.contains(newAssertion)) {
							System.out.println("Success: " + newAssertion);
							wm.addAssertion(newAssertion);
							newAssertionCreated = true;
						}
					}
				}
			}
			System.out.println("Working Memory" + wm);
		} while (newAssertionCreated);
		System.out.println("No rule produces a new assertion");
	}

}
